﻿using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
using Netkk.Core.Auth;
using Netkk.Library;
using SiteMapNode=Netkk.Library.SiteMapNode;

namespace Netkk.Core
{
    public static class HtmlHelperExtensions
    {
        public static string PagerLinks(this HtmlHelper htmlHelper, string controllerName, string actionName, int pageCount, int pageIndex, string cssClass, string moreTextCssClass, string currentPageCssClass)
        {
            return PagerLinks(htmlHelper, controllerName, actionName, pageCount, pageIndex, "Erste", "Vorige", "Weiter", "Letzte", "Mehr: ", cssClass, moreTextCssClass, currentPageCssClass);
        }

        public static string PagerLinks(this HtmlHelper htmlHelper, string controllerName, string actionName, int pageCount, int pageIndex, string firstPage, string previousPage, string nextPage, string lastPage, string moreText, string cssClass, string moreTextCssClass, string currentPageCssClass)
        {
            var builder = new StringBuilder();
            if (String.IsNullOrEmpty(controllerName) || String.IsNullOrEmpty(actionName))
                throw new Exception("controllerName and actionName must be specified for PageLinks.");
            if (pageCount <= 1)
                return String.Empty;


            if (
                String.IsNullOrEmpty(cssClass))
            {
                builder.Append("<div>");
            }
            else
            {
                builder.Append(String.Format("<div class=\"{0}\">", cssClass));
            }

            if (String.IsNullOrEmpty(moreTextCssClass))
            {
                builder.Append(String.Format("<span>{0}</span> ", moreText));
            }
            else
            {
                builder.Append(String.Format("<span class=\"{0}\">{1}</span> ", moreTextCssClass, moreText));
            }

            if (pageIndex != 1)
            {
                // first page link
                builder.Append(htmlHelper.RouteLink("|<", new { controller = controllerName, action = actionName, id = 1 }, new { title = firstPage }));
                builder.Append(" ");
                if (pageIndex > 2)
                {
                    // previous page link
                    int previousLink = pageIndex - 1;
                    builder.Append(htmlHelper.RouteLink("<<", new { controller = controllerName, action = actionName, id = previousLink }, new { title = previousPage }));
                    builder.Append(" ");
                }
            }
            // calc low and high limits for numeric links
            int intLow = pageIndex - 1;
            int intHigh = pageIndex + 3;
            if (intLow < 1) intLow = 1;
            if (intHigh > pageCount) intHigh = pageCount;
            if (intHigh - intLow < 5) while ((intHigh < intLow + 4) && intHigh < pageCount) intHigh++;
            if (intHigh - intLow < 5) while ((intLow > intHigh - 4) && intLow > 1) intLow--;
            for (int x = intLow; x < intHigh + 1; x++)
            {
                // numeric links
                if (x == pageIndex)
                {
                    if (String.IsNullOrEmpty(currentPageCssClass))
                    {
                        builder.Append(String.Format("<span>{0} von {1}</span> ", x, pageCount));
                    }
                    else
                    {
                        builder.Append(String.Format("<span class=\"{0}\">{1} von {2}</span> ", currentPageCssClass, x, pageCount));
                    }
                }
                else
                {
                    builder.Append(htmlHelper.RouteLink(x.ToString(), new { controller = controllerName, action = actionName, id = x }));
                    builder.Append(" ");
                }
            }
            if (pageIndex != pageCount)
            {
                if (pageIndex < pageCount - 1)
                {
                    // next page link
                    int nextLink = pageIndex + 1;
                    builder.Append(htmlHelper.RouteLink(">>", new { controller = controllerName, action = actionName, id = nextLink }, new { title = nextPage }));
                    builder.Append(" ");
                }
                // last page link
                builder.Append(htmlHelper.RouteLink(">|", new { controller = controllerName, action = actionName, id = pageCount }, new { title = lastPage }));
                builder.Append(" ");
            }
            builder.Append("</div>");

            return builder.ToString();
        }



        /// <summary>
        /// Menus the specified helper.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <returns></returns>
        public static string Menu(this HtmlHelper helper)
        {
            var sb = new StringBuilder();

            var topLevelNodes = Sitemap.Current().RootNode.ChildNodes;
            if (topLevelNodes.Count > 0)
            {
                // Create opening unordered list tag
                sb.Append("<ul>");

                // Render each top level node
                foreach (SiteMapNode node in topLevelNodes)
                {
                    if(!node.Visible)
                        continue;

                    if (Sitemap.Current().CurrentNode == node || CheckCurrentNodeInPath(node))
                    {
                        sb.AppendLine("<li class=\"selected\">");
                    }
                    else
                    {
                        sb.AppendLine("<li>");
                    }

                    sb.AppendFormat("<a href=\"{0}\"><span>{1}</span></a>", helper.Action(node.Controller, node.Action, node.ParamId), helper.Encode(node.Title));
                    sb.AppendLine("</li>");
                }

                // Close unordered list tag
                sb.Append("</ul>");
            }

            return sb.ToString();
        }

        /// <summary>
        /// Menus the specified helper.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <returns></returns>
        public static string SubMenu(this HtmlHelper helper)
        {
            var sb = new StringBuilder();

            var nodes = Sitemap.Current().RootNode.ChildNodes;
            if (nodes.Count > 0)
            {
                // Create opening unordered list tag
                sb.Append("<ul class=\"submenu\">");

                // Render each top level node
                foreach (SiteMapNode node in nodes)
                {
                    if (CheckCurrentNodeInPath(node))
                    {
                        foreach (SiteMapNode subnode in node.ChildNodes)
                        {
                            if(!subnode.Visible)
                                continue;

                            if (Sitemap.Current().CurrentNode == subnode)
                            {
                                sb.AppendLine("<li class=\"selected\">");
                            }
                            else
                            {
                                sb.AppendLine("<li>");
                            }

                            sb.AppendFormat("<a href=\"{0}\"><span>{1}</span></a>", helper.Action(subnode.Controller, subnode.Action, subnode.ParamId), helper.Encode(subnode.Title));
                            sb.AppendLine("</li>");
                        }
                    }
                }

                // Close unordered list tag
                sb.Append("</ul>");
            }

            return sb.ToString();
        }

        private static bool CheckCurrentNodeInPath(SiteMapNode node)
        {
            SiteMapNode pathNode = Sitemap.Current().FindSiteMapNode(HttpContext.Current);

            if (pathNode == null)
            {
                return false;
            }
            while(pathNode != null && Sitemap.Current().RootNode != pathNode)
            {

                if (node == pathNode)
                {
                    return true;
                }
                pathNode = pathNode.ParentNode;
            }
            return false;
        }

        public static string Action(this HtmlHelper htmlHelper, string controllerName, string actionName)
        {
            RouteValueDictionary rvd = new RouteValueDictionary
                                           {
                                               {"controller", controllerName}, 
                                               {"action", actionName}
                                           };
            return RouteTable.Routes.GetVirtualPath(htmlHelper.ViewContext.RequestContext, rvd).VirtualPath;
        }

        public static string Action(this HtmlHelper htmlHelper, string controllerName, string actionName, Guid id)
        {
            RouteValueDictionary rvd = new RouteValueDictionary
                                           {
                                               {"controller", controllerName},
                                               {"action", actionName},
                                               {"id", id}
                                           };
            return RouteTable.Routes.GetVirtualPath(htmlHelper.ViewContext.RequestContext, rvd).VirtualPath;
        }

        public static string Action(this HtmlHelper htmlHelper, string controllerName, string actionName, string id)
        {
            RouteValueDictionary rvd = new RouteValueDictionary
                                           {
                                               {"controller", controllerName},
                                               {"action", actionName},
                                               {"id", id}
                                           };
            return RouteTable.Routes.GetVirtualPath(htmlHelper.ViewContext.RequestContext, rvd).VirtualPath;
        }

        public static string CurrentUserProfileLink(this HtmlHelper htmlHelper)
        {
            CustomIdentity identity = ((CustomIdentity)htmlHelper.ViewContext.RequestContext.HttpContext.User.Identity);
            string username;
            if (!String.IsNullOrEmpty(identity.User.FirstName) && !String.IsNullOrEmpty(identity.User.LastName))
            {
                username = identity.User.FirstName + " " + identity.User.LastName;
            }
            else if (!String.IsNullOrEmpty(identity.User.FirstName))
            {
                username = identity.User.FirstName;
            }
            else
            {
                username = identity.User.Name;
            }
            return htmlHelper.RouteLink(username, new
                                                      {
                                                          Action = "Details",
                                                          Controller = "Member"
                                                      });
        }

        public static string CurrentUserEditLink(this HtmlHelper htmlHelper)
        {
            CustomIdentity identity = ((CustomIdentity)htmlHelper.ViewContext.RequestContext.HttpContext.User.Identity);
            string username;
            if (!String.IsNullOrEmpty(identity.User.FirstName) && !String.IsNullOrEmpty(identity.User.LastName))
            {
                username = identity.User.FirstName + " " + identity.User.LastName;
            }
            else if (!String.IsNullOrEmpty(identity.User.FirstName))
            {
                username = identity.User.FirstName;
            }
            else
            {
                username = identity.User.Name;
            }
            return htmlHelper.RouteLink(username, new
                                                      {
                                                          Action = "Edit",
                                                          Controller = "Member",
                                                          id = identity.User.Id
                                                      });
        }
    }
}